package entityMapping.demo3.bean;

import entityMapping.demo3.enums.AccountSettingType;
import entityMapping.demo3.enums.LiveTradingType;

import javax.persistence.*;
import java.util.Date;

@Entity
@Table(name = "ACCOUNT_SETTINGS")
public class AccountSetting extends DataObject {

    private Default dft;

    /**
     * 给 Hibernate 用的，其他地方不要用，会在 Server.java 中补回 Default dft
     */
    public AccountSetting() {
    }

    public AccountSetting(String accountId, Default dft) {
        this.dft = dft;
        setId(accountId);
    }

    //!!! very important: you must add entry here whenever you add a setting
    public static AccountSetting createEmptySettings(String accountId, Default dft) {
        AccountSetting settings = new AccountSetting(accountId, dft);
        settings.setLiveTrading(dft.isLiveTrading());
        settings.setFreezeValue(dft.getFreezeValue());
        settings.setTerminateValue(dft.getTerminateValue());
        settings.setFreezePercent(dft.getFreezePercent());
        settings.setTerminatePercent(dft.getTerminatePercent());
        return settings;
    }

    /**
     * reset to default value
     */
    public void reset() {
        this.setLiveTrading(dft.isLiveTrading());
        this.setFreezeValue(dft.getFreezeValue());
        this.setTerminateValue(dft.getTerminateValue());
        this.setFreezePercent(dft.getFreezePercent());
        this.setTerminatePercent(dft.getTerminatePercent());
    }

    @Id
    @Column(name = "ACCOUNT_ID")
    public String getId() {
        return get(String.class, AccountSettingType.ID.value());
    }

    public void setId(String id) {
        put(AccountSettingType.ID.value(), id);
    }

    @Transient
    public Double getDefaultQty() {
        Double result = get(double.class, AccountSettingType.DEFAULT_QTY.value());
        return null == result ? dft.getOrderQuantity() : result;
    }

    public void setDefaultQty(Double defaultQty) {
        put(AccountSettingType.DEFAULT_QTY.value(), defaultQty);
    }

    @Transient
    public double getStopLossValue() {
        Double result = get(double.class, AccountSettingType.STOP_LOSS_VALUE.value());
        return null == result ? dft.getPositionStopLoss() : result;
    }

    public void setStopLossValue(double stopLossValue) {
        put(AccountSettingType.STOP_LOSS_VALUE.value(), stopLossValue);
    }

    @Transient
    public double getCompanySLValue() {
        return get(double.class, AccountSettingType.COMPANY_SL_VALUE.value());
    }

    public void setCompanySLValue(double companySLValue) {
        put(AccountSettingType.COMPANY_SL_VALUE.value(), companySLValue);
    }

    @Transient
    public double getMargin() {
        return get(double.class, AccountSettingType.MARGIN.value());
    }

    public void setMargin(double margin) {
        put(AccountSettingType.MARGIN.value(), margin);
    }

    @Transient
    public String getRoute() {
        return get(String.class, AccountSettingType.ROUTE.value());
    }

    public void setRoute(String route) {
        put(AccountSettingType.ROUTE.value(), route);
    }

    @Transient
    public double getLeverageRate() {
        return get(double.class, AccountSettingType.LEVERAGE_RATE.value());
    }

    public void setLeverageRate(double lRate) {
        put(AccountSettingType.LEVERAGE_RATE.value(), lRate);
    }

    @Transient
    public double getCommission() {
        return get(double.class, AccountSettingType.COMMISSION.value());
    }

    public void setCommission(double commission) {
        put(AccountSettingType.COMMISSION.value(), commission);
    }

    @Transient
    public double getDailyStopLoss() {
        return get(double.class, AccountSettingType.DAILY_STOPLOSS.value());
    }

    public void setDailyStopLoss(double dailyStopLoss) {
        put(AccountSettingType.DAILY_STOPLOSS.value(), dailyStopLoss);
    }

    @Transient
    public double getTrailingStop() {
        return get(double.class, AccountSettingType.TRAILING_STOP.value());
    }

    public void setTrailingStop(double trailingStop) {
        put(AccountSettingType.TRAILING_STOP.value(), trailingStop);
    }

    @Transient
    public double getStopLossPercent() {
        return get(double.class, AccountSettingType.STOP_LOSS_PERCENT.value());
    }

    public void setStopLossPercent(double stopLossPercent) {
        put(AccountSettingType.STOP_LOSS_PERCENT.value(), stopLossPercent);
    }

    @Column(name = "FREEZE_PERCENT")
    public double getFreezePercent() {
        return get(double.class, AccountSettingType.FREEZE_PERCENT.value());
    }

    public void setFreezePercent(double freezePercent) {
        put(AccountSettingType.FREEZE_PERCENT.value(), freezePercent);
    }

    @Column(name = "TERMINATE_PERCENT")
    public double getTerminatePercent() {
        return get(double.class, AccountSettingType.TERMINATE_PERCENT.value());
    }

    public void setTerminatePercent(double terminatePercent) {
        put(AccountSettingType.TERMINATE_PERCENT.value(), terminatePercent);
    }

    @Column(name = "LIVE_TRADING")
    public boolean isLiveTrading() {
        return get(boolean.class, AccountSettingType.LIVE_TRADING.value());
    }

    public void setLiveTrading(boolean liveTrading) {
        put(AccountSettingType.LIVE_TRADING.value(), liveTrading);
    }

    @Transient
    public boolean isUserLiveTrading() {
        return get(boolean.class, AccountSettingType.USER_LIVE_TRADING.value());
    }

    public void setUserLiveTrading(boolean userLiveTrading) {
        put(AccountSettingType.USER_LIVE_TRADING.value(), userLiveTrading);
    }

    @Transient
    public LiveTradingType getLiveTradingType() {
        return dft.getLiveTradingType();
    }

    public void setLiveTradingType(LiveTradingType liveTradingType) {
    }

    @Transient
    public String getLiveTradingSettedDate() {
        return "";
    }

    public void setLiveTradingSettedDate(String liveTradingSettedDate) {

    }

    @Column(name = "FREEZE_VALUE")
    public double getFreezeValue() {
        return get(double.class, AccountSettingType.FREEZE_VALUE.value());
    }

    public void setFreezeValue(double freezeValue) {
        put(AccountSettingType.FREEZE_VALUE.value(), freezeValue);
    }

    @Column(name = "TERMINATE_VALUE")
    public double getTerminateValue() {
        return get(double.class, AccountSettingType.TERMINATE_VALUE.value());
    }

    public void setTerminateValue(double terminateValue) {
        put(AccountSettingType.TERMINATE_VALUE.value(), terminateValue);
    }

    @Transient
    public String getDefaultQty2() {
        return get(String.class, AccountSettingType.DEFAULT_QTY2.value());
    }

    public void setDefaultQty2(String defaultQty2) {
        put(AccountSettingType.DEFAULT_QTY2.value(), defaultQty2);
    }

    @Transient
    public boolean isLtsApiPerm() {
        return get(boolean.class, AccountSettingType.LTS_API_PERM.value());
    }

    public void setLtsApiPerm(boolean ltsApiPerm) {
        put(AccountSettingType.LTS_API_PERM.value(), ltsApiPerm);
    }

    public boolean checkLiveTrading() {
        return (isLiveTrading() || isUserLiveTrading());
    }

    @Transient
    public boolean isSkipPoolCheck() {
        return get(boolean.class, AccountSettingType.SKIP_POOL_CHECK.value());
    }

    public void setSkipPoolCheck(boolean skipPoolCheck) {
        put(AccountSettingType.SKIP_POOL_CHECK.value(), skipPoolCheck);
    }

    @Transient
    public boolean isNoAverageDown() {
        return get(boolean.class, AccountSettingType.NO_AVERAGE_DOWN.value());
    }

    public void setNoAverageDown(boolean noAverageDown) {
        put(AccountSettingType.NO_AVERAGE_DOWN.value(), noAverageDown);
    }

    @Transient
    public Date getNoAverageDownLeastLast() {
        return get(Date.class, AccountSettingType.NO_AVERAGE_DOWN_LEAST_LAST.value());
    }

    public void setNoAverageDownLeastLast(Date noAverageDownLeastLast) {
        put(AccountSettingType.NO_AVERAGE_DOWN_LEAST_LAST.value(), noAverageDownLeastLast);
    }

    @Transient
    public double getStopWinValue() {
        return get(double.class, AccountSettingType.STOP_WIN_VALUE.value());
    }

    public void setStopWinValue(double stopWinValue) {
        put(AccountSettingType.STOP_WIN_VALUE.value(), stopWinValue);
    }

    @Transient
    public double getReservedBuyingPowerPercentage() {
        return get(double.class, AccountSettingType.RESERVED_BUYING_POWER_PERCENTAGE.value());
    }

    public void setReservedBuyingPowerPercentage(double reservedBuyingPowerPercentage) {
        put(AccountSettingType.RESERVED_BUYING_POWER_PERCENTAGE.value(), reservedBuyingPowerPercentage);
    }

    @Transient
    public boolean isCompanyDayTrading() {
        return get(boolean.class, AccountSettingType.COMPANY_DAY_TRADING.value());
    }

    public void setCompanyDayTrading(boolean companyDayTrading) {
        put(AccountSettingType.COMPANY_DAY_TRADING.value(), companyDayTrading);
    }

    @Transient
    public Default getDefault() {
        return dft;
    }

    public void setDft(Default dft) {
        this.dft = dft;
    }

    public AccountSetting clone() {
        return (AccountSetting) super.clone();
    }

    @Override
    public String toString() {
        return this.getFields().toString();
    }
}
